package com.version1_3.service.implement;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.util.format.MapToJson;
import com.util.property.Properties;
import com.version1_1.dao.UserDao;
import com.version1_1.model.User;
import com.version1_1.service.RongCloudService;
import com.version1_3.controller.UserController1_3;
import com.version1_3.dao.ActivityDao;
import com.version1_3.dao.ShareDao;
import com.version1_3.dao.UserDao1_3;
import com.version1_3.model.UserModel;
import com.version1_3.service.CoinService;
import com.version1_3.service.UserSerivce1_3;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by kuibu on 15/12/25.
 */
@Service
public class UserSerivceImpl13 implements UserSerivce1_3 {
    private static final Logger LOGGER = Logger.getLogger(UserController1_3.class);

    @Autowired
    private UserDao1_3 userDao13;

    @Autowired
    private UserDao userDao;

    @Autowired
    private ShareDao shareDao;

    @Autowired
    private RongCloudService rongCloudService;

    @Autowired
    private CoinService coinService; // 积分记录服务层

    @Autowired
    private ActivityDao activityDao; // 活动DAO层

    /**
     * 网页端注册
     */
    @Override
    public String htmlRegister(String telnumber, String password, String inviteCode) {
        // 无有效参数
        if ("".equals(telnumber)) {
            LOGGER.error("用户注册，无手机号...");
            return "{\"isCorrect\":false,\"type\":0,\"userId\":-1}";
        }
        // 参数错误
        if (!"".equals(telnumber)) {
            // 手机号已存在
            if (userDao.checkUserExist("", telnumber)) {
                LOGGER.error("用户注册,手机号已存在...");
                return "{\"isCorrect\":false,\"type\":4,\"userId\":-1}";
            }
            // 手机号不是11位
            if (telnumber.length() != 11) {
                LOGGER.error("用户注册,手机号不是11位...");
                return "{\"isCorrect\":false,\"type\":2,\"userId\":-1}";
            }
        }

        // 用户注册
        int userId = userDao13.htmlRegister(telnumber, password, inviteCode);
        User user = userDao.getUserInfo(userId);

        if (user == null) {
            LOGGER.error("根据userId得到用户对象错误");
            return "{\"isCorrect\":false,\"type\":3,\"userId\":-1}";
        } else {
            String userInviteCode = userDao.updateUserInviteCode(userId);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("inviteCode", userInviteCode);
            resultMap.put("isCorrect", true);
            resultMap.put("userId", user.getUserId());
            // 返回邀请码
            return net.sf.json.JSONObject.fromObject(resultMap).toString();
        }
    }

    /**
     * 带邀请码注册
     */
    @Override
    public String registerWithInviteCode(String telnumber, String password, String inviteCode) {
        // 无有效参数
        if ("".equals(telnumber)) {
            LOGGER.error("用户注册，无手机号...");
            return "{\"isCorrect\":false,\"type\":0,\"userId\":-1}";
        }
        // 参数错误
        if (!"".equals(telnumber)) {
            // 手机号已存在
            if (userDao.checkUserExist("", telnumber)) {
                LOGGER.error("用户注册,手机号已存在...");
                return "{\"isCorrect\":false,\"type\":4,\"userId\":-1}";
            }
            // 手机号不是11位
            if (telnumber.length() != 11) {
                LOGGER.error("用户注册,手机号不是11位...");
                return "{\"isCorrect\":false,\"type\":2,\"userId\":-1}";
            }
        }

        // 用户注册
        int userId = userDao13.registerWithInviteCode(telnumber, password, inviteCode, "");
        User user = userDao.getUserInfo(userId);

        if (user == null) {
            LOGGER.error("根据userId得到用户对象错误");
            return "{\"isCorrect\":false,\"type\":3,\"userId\":-1}";
        } else {
            String userInviteCode = userDao.updateUserInviteCode(userId);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("inviteCode", userInviteCode);
            resultMap.put("isCorrect", true);
            resultMap.put("userId", user.getUserId());
            // 返回邀请码
            return net.sf.json.JSONObject.fromObject(resultMap).toString();
        }
    }

    /**
     * 获取用户邀请码
     */
    @Override
    public String getInviteCode(String telnumber) {
        String inviteCode = userDao13.getInviteCode(telnumber);
        int inviteFriendsNumber = shareDao.getUserInvitedFriends(inviteCode);
        Map<String, Object> inviteInfoMap = new HashMap<>();

        if (inviteCode == null) {
            // 如果没有找到用户邀请码
            inviteInfoMap.put("inviteCode", "null");
        } else {
            inviteInfoMap.put("inviteCode", inviteCode);
            inviteInfoMap.put("inviteFirendsNumber", inviteFriendsNumber);
        }

        return net.sf.json.JSONObject.fromObject(inviteInfoMap).toString();
    }

    /**
     * 更新用户某个一级分类下的关注分类信息(包括三级分类内容和三级分类顺序)
     */
    @Override
    public String updateFirstFocus(JSONArray firstFocusJsonArray, int firstType, int userId) {

        if (firstType - 2 < 0 || firstType - 2 > 3) {
            LOGGER.error("客户端发送一级分类ID超出范围,firstType: " + firstType);
            return "{\"code\":500}";
        }

        MapToJson mapToJson = new MapToJson("sortSecondTypeResult", userDao13.updateFirstFocus(firstFocusJsonArray, firstType, userId));
        return mapToJson.toJsonString();
    }

    @Override
    public String topThirdType(int thirdType, int firstType, int userId) {

        if (firstType - 2 < 0 || firstType - 2 > 3) {
            LOGGER.error("三级分类置顶,客户端发送一级分类ID超出范围,firstType: " + firstType);
            return "{\"code\":500}";
        }

        if (userId == -1) {
            LOGGER.error("三级分类置顶,userId为-1");
            return "{\"code\":500}";
        }

        MapToJson mapToJson = new MapToJson("topThirdTypeResult", userDao13.topThirdType(thirdType, firstType, userId));
        return mapToJson.toJsonString();
    }

    /**
     * 取消三级分类置顶
     */
    @Override
    public String removeTopThirdType(int thirdType, int firstType, int userId) {
        if (firstType - 2 < 0 || firstType - 2 > 3) {
            LOGGER.error("三级分类置顶,客户端发送一级分类ID超出范围,firstType: " + firstType);
            return "{\"code\":500}";
        }

        if (userId == -1) {
            LOGGER.error("三级分类置顶,userId为-1");
            return "{\"code\":500}";
        }

        MapToJson mapToJson = new MapToJson("removeTopThirdTypeResult", userDao13.removeTopThirdType(thirdType, firstType, userId));
        return mapToJson.toJsonString();
    }

    @Override
    public String updateFocusList(JSONArray jsonArray, int userId) {
        MapToJson mapToJson = new MapToJson("updateFocusResult", userDao13.updateFocusList(jsonArray, userId));
        return mapToJson.toJsonString();
    }

    /**
     * 用户登陆
     */
    @Override
    public String login(int userId, String telnumber, String password, String baiduId) {
        boolean isUserExist = userDao.checkUserExist("", telnumber);

        // 检测到用户不存在
        if (!isUserExist) {
            return "{\"userId\":-1,\"errorType\":0}";
        }
        UserModel userModel = userDao13.login(userId, telnumber, password);

        // 密码错误,登陆失败
        if (userModel == null) {
            return "{\"userId\":-1,\"errorType\":1}";
        }

        // 获取用户token
        String userToken = "";

        // 获取用户收藏字符串
        String userCollect = userDao.getCollectString(userId, "", telnumber);

        userModel.setTokenRY(userToken);
        userModel.setUserCollect(userCollect);

        coinService.recordUserLogin(userModel.getUserId()); // 登陆加积分 03.06

        userDao.updateUserBaiduId(baiduId, userModel.getUserId());

        return userModel.jsonSerialize();
    }

    /**
     * 搜索学校
     **/
    @Override
    public String searchSchool(String schoolKey) {
        List<Map<String, Object>> schoolMapList = userDao13.searchSchool(schoolKey);
        return new MapToJson("searchSchoolResult", schoolMapList).toJsonString();
    }

    /**
     * 第三方注册或是刷新token - iOS版本
     *
     * @param openid
     * @param token
     */
    @Override
    public String thirdPartRegister(String platform, String openid, String token, String uuid, String baiduId) {
        Map<String, Object> userInfoMap = userDao13.getUserInfoWithThirdPartLogin(openid, "iOS");
        String userInfo = "";

        if (userInfoMap == null) {
            // 根据第三方openid找不到注册用户,需要注册新用户
            int userId = userDao13.registerWithThirdPartLogin(openid, token, uuid);

            // 设置用户的baiduId
            userDao.updateUserBaiduId(baiduId, userId);

            userDao.updateUserInviteCode(userId); // 第三方登陆增加属于自己的邀请码 3.17,临时新增功能

            // 需要的第三方信息主要有: 头像(userPhoto),昵称(userName),性别(userSex)三个
            Map<String, Object> thirdPartUserInfo = shareDao.getThirdPartUserInfoMap(platform, "iOS", openid, token);

            // 根据第三方平台信息更新用户信息
            userDao.updateUserInfo(userId, (String) thirdPartUserInfo.get("userName"), (String) thirdPartUserInfo.get("userPhoto"), (String) thirdPartUserInfo.get("userSex"));


            /*IOS用户发送的关注分类信息格式和Android用户不同,此版本是IOS版本*/
            UserModel userModel = userDao13.getUserInfo(openid);
            // 获取用户收藏字符串
            String userCollect = userDao.getCollectString(userId, "", "");
            userModel.setUserCollect(userCollect);

            // userDao.updateUserInviteCode(userId); // 第三方注册目前不开放邀请码功能

            userInfo = userModel.jsonSerialize();
        } else {
            userDao13.freshUserToken((int) userInfoMap.get("userId"), token);

            UserModel userModel = userDao13.getUserInfo(openid);
            // 获取用户收藏字符串
            String userCollect = userDao.getCollectString((int) userInfoMap.get("userId"), "", "");
            userModel.setUserCollect(userCollect);

            userInfo = userModel.jsonSerialize();

            coinService.recordUserLogin((int) userInfoMap.get("userId")); // 登陆加积分 03.12
        }

        return userInfo;
    }

    /**
     * 第三方注册或是刷新token - Android版本
     *
     * @param platform
     * @param openid
     * @param token
     */
    @Override
    public String thirdPartRegisterAndroid(String platform, String openid, String token, String uuid, String baiduId) {

        Map<String, Object> userInfoMap = userDao13.getUserInfoWithThirdPartLogin(openid, "Android");
        String userInfo = "";

        if (userInfoMap == null) {
            // 根据第三方openid找不到注册用户,需要注册新用户
            int userId = userDao13.registerWithThirdPartLogin(openid, token, uuid);

            // 设置用户的baiduId
            userDao.updateUserBaiduId(baiduId, userId);

            userDao.updateUserInviteCode(userId); // 第三方登陆增加属于自己的邀请码 3.17,临时新增功能

            // 需要的第三方信息主要有: 头像(userPhoto),昵称(userName),性别(userSex)三个
            Map<String, Object> thirdPartUserInfo = shareDao.getThirdPartUserInfoMap(platform, "android", openid, token);

            // 根据第三方平台信息更新用户信息
            userDao.updateUserInfo(userId, (String) thirdPartUserInfo.get("userName"), (String) thirdPartUserInfo.get("userPhoto"), (String) thirdPartUserInfo.get("userSex"));


            /*IOS用户发送的关注分类信息格式和Android用户不同,此版本是Android版本*/
            UserModel userModel = userDao13.getUserInfoAnroid(openid);
            // 获取用户收藏字符串
            String userCollect = userDao.getCollectString(userId, "", "");
            userModel.setUserCollect(userCollect);

            // userDao.updateUserInviteCode(userId); // 第三方注册目前不开放邀请码功能

            userInfo = userModel.jsonSerialize();
        } else {
            userDao13.freshUserToken((int) userInfoMap.get("userId"), token);
            UserModel userModel = userDao13.getUserInfoAnroid(openid);
            // 获取用户收藏字符串
            String userCollect = userDao.getCollectString((int) userInfoMap.get("userId"), "", "");
            userModel.setUserCollect(userCollect);

            userInfo = userModel.jsonSerialize();

            coinService.recordUserLogin((int) userInfoMap.get("userId")); // 登陆加积分 03.06
        }

        return userInfo;
    }

    /**
     * 第三方平台根据openid获取用户信息
     *
     * @param openid
     * @return
     */
    @Override
    public String thirdPartLogin(String openid, String os, String baiduId) {
        Map<String, Object> userInfoMap = userDao13.getUserInfoWithThirdPartLogin(openid, os);

        if (userInfoMap == null) {
            return "{\"error\"}";
        } else {
            userDao.updateUserBaiduId(baiduId, (int) userInfoMap.get("userId"));
            return net.sf.json.JSONObject.fromObject(userInfoMap).toString();
        }
    }


    /**
     * 用户注册,必须填写学校信息
     *
     * @param telnumber
     * @param password
     * @param inviteCode
     * @param school
     * @return
     */
    @Override
    public String registerSchoolNeeded(String telnumber, String password, String inviteCode, String school, String uuid) {
        // 无有效参数
        if ("".equals(telnumber)) {
            LOGGER.error("用户注册，无手机号...");
            return "{\"isCorrect\":false,\"type\":0,\"userId\":-1}";
        }
        // 参数错误
        if (!"".equals(telnumber)) {
            // 手机号已存在
            if (userDao.checkUserExist("", telnumber)) {
                LOGGER.error("用户注册,手机号已存在,telnumber: " + telnumber);
                return "{\"isCorrect\":false,\"type\":4,\"userId\":-1}";
            }
            // 手机号不是11位
            if (telnumber.length() != 11) {
                LOGGER.error("用户注册,手机号不是11位...");
                return "{\"isCorrect\":false,\"type\":2,\"userId\":-1}";
            }
        }

        if (school.isEmpty() || "null".equals(school)) {
            return "{\"isCorrect\":false,\"type\":3,\"userId\":-1}";
        }

        // 用户注册,验证邀请码格式
        if (inviteCode.isEmpty() || !(inviteCode.contains("kb"))) {
            inviteCode = "null";
        }

        int userId = userDao13.registerWithInviteCode(telnumber, password, inviteCode, uuid);
        User user = userDao.getUserInfo(userId);

        if (user == null) {
            LOGGER.error("根据userId得到用户对象错误");
            return "{\"isCorrect\":false,\"type\":3,\"userId\":-1}";
        } else {
            String userInviteCode = userDao.updateUserInviteCode(userId);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("isCorrect", userDao.updateUserInfo(userId, "", "", "", school, -1)); // 更新学校信息
            resultMap.put("userId", user.getUserId());

            // 返回注册结果
            return net.sf.json.JSONObject.fromObject(resultMap).toString();
        }
    }

    /**
     * 获取用户日积跬步页面
     *
     * @param userId
     */
    @Override
    @Cacheable(value = {"accumulatePageCache"})
    @CacheEvict(value = "accumulatePageCache", condition = "#cleanCache==true", allEntries = true)
    public String getAccumulatePage(int userId, boolean cleanCache) {

        Map<String, Object> accumulatePageMap = new HashMap<>(); // 日积跬步

        Map<String, Object> userInfoMap = userDao13.getUserInfo(userId);
        String userName = (String) userInfoMap.get("userName"); // 1. 用户昵称
        String userPhoto = (String) userInfoMap.get("userPhoto"); // 2. 用户头像
        String school = (String) userInfoMap.get("school"); // 用户学校

        boolean hasCompleteUserInfo = false; // 3. 用户是否完善信息
        if (userName != null && userPhoto != null && school != null && !userName.isEmpty() && !userPhoto.isEmpty() && !school.isEmpty()) {
            hasCompleteUserInfo = true;
            coinService.recordUserCompleteInfoCoin(userId);
        }

        int readArticleCoin = userDao13.getModuleCoin(userId, "information", "readArticle"); // 7. 阅读文章积分
        int collectArticleCoin = userDao13.getModuleCoin(userId, "information", "collectArticle"); // 8. 收藏文章积分
        int articleCommentCoin = userDao13.getModuleCoin(userId, "information", "commentInPageOrReply"); // 9. 文章评论积分
        int shareArticleCoin = userDao13.getModuleCoin(userId, "information", "shareArticle"); // 10. 分享文章积分
        int articlePraiseCoin = userDao13.getModuleCoin(userId, "information", "goodOrBadArticle"); // 11. 文章点赞积分

        int activityGongyipaoCoin = 0;
        int activityGongyipaoCoinCount = 0;
        Map launchPageInfoMap = activityDao.getUserLaunchPageInfo(userId, 11);
        if (launchPageInfoMap != null) {
            // 获取身高体重信息,用来计算跑路里程和卡路里
            Map<String, Object> userBodyInfoMap = userDao13.getUserBodyInfo(userId);
            double mileCount = ((BigDecimal) userBodyInfoMap.get("height")).intValue() * 0.0075 * ((BigDecimal) launchPageInfoMap.get("currData")).intValue();
            activityGongyipaoCoin = (int) (mileCount / 1000); // 12. 跬步公益跑当日积分

            mileCount = ((BigDecimal) userBodyInfoMap.get("height")).intValue() * 0.0075 * ((BigDecimal) launchPageInfoMap.get("currDataCount")).intValue();
            activityGongyipaoCoinCount = (int) (mileCount / 1000); // 公益跑总积分
        }

        String userJoinedActivityIds = userDao13.getUserJoinedActivityIds(userId);
        int activityTopCoin = JSONArray.parseArray(userJoinedActivityIds).size() * 10; // 13. 活动最高积分,根据参加了几个活动

        int activityLaunchCardCoin = activityDao.getUserLaunchCardCoin(userId); // 14. 活动打卡积分
        int activityShareCoin = activityDao.getActivityShareCoin(userId); // 15. 活动分享积分


        int todayCoin = readArticleCoin + collectArticleCoin + articleCommentCoin + shareArticleCoin + articlePraiseCoin + activityLaunchCardCoin + activityShareCoin; // 6. 今日累计积分

        Map<String, Object> levelMap = getLevel(userDao13.getUserCountCoin(userId) + activityGongyipaoCoinCount + userDao13.getUserDaysCoinCount(userId) + activityTopCoin); // 用户总积分是user_info中积分加上跬步公益跑总积分
        int level = (int) levelMap.get("level"); // 4. 用户等级
        int topCoin = (int) levelMap.get("topCoin");

        int userCountCoin = userDao13.getUserCountCoin(userId) + activityGongyipaoCoinCount + userDao13.getUserDaysCoinCount(userId) + activityTopCoin; // 5. 用户总积分

        accumulatePageMap.put("userName", userName); // 1. 用户昵称
        accumulatePageMap.put("userPhoto", userPhoto); // 2. 用户头像
        accumulatePageMap.put("completeUserInfo", hasCompleteUserInfo); // 3. 是否完善个人信息
        accumulatePageMap.put("level", level); // 4. 用户等级
        accumulatePageMap.put("userCoin", userCountCoin); // 5. 用户积分
        accumulatePageMap.put("levelTopCoin", topCoin); // 6. 用户所处等级最高积分
        accumulatePageMap.put("todayCoin", todayCoin); // 7. 今日累计积分
        accumulatePageMap.put("readArticleCoin", readArticleCoin); // 8. 阅读文章积分
        accumulatePageMap.put("collectArticleCoin", collectArticleCoin); // 9. 收藏文章积分
        accumulatePageMap.put("articleCommentCoin", articleCommentCoin); // 10. 文章评论积分
        accumulatePageMap.put("shareArticleCoin", shareArticleCoin); // 11. 分享文章积分
        accumulatePageMap.put("articlePraiseCoin", articlePraiseCoin); // 12. 文章点赞积分
        accumulatePageMap.put("activityGongyipaoCoin", activityGongyipaoCoin); // 13. 公益跑积分
        accumulatePageMap.put("activityTopCoin", activityTopCoin); // 14. 活动最高积分
        accumulatePageMap.put("activityLaunchCardCoin", activityLaunchCardCoin); // 15. 打卡积分
        accumulatePageMap.put("activityShareCoin", activityShareCoin); // 16. 分享积分

        return net.sf.json.JSONObject.fromObject(accumulatePageMap).toString();
    }


    /*
     * 工具方法,根据
     */
    private Map<String, Object> getLevel(int todayCoin) {
        Map<String, Object> userLevelMap = new HashMap<>();

        if (todayCoin > 0 && todayCoin <= 60) {
            // 第0等级
            userLevelMap.put("level", 0);
            userLevelMap.put("topCoin", 60);

        } else if (todayCoin > 60 && todayCoin <= 360) {
            // 第1等级
            userLevelMap.put("level", 1);
            userLevelMap.put("topCoin", 360);

        } else if (todayCoin > 360 && todayCoin <= 960) {
            // 第2等级
            userLevelMap.put("level", 2);
            userLevelMap.put("topCoin", 960);

        } else if (todayCoin > 960 && todayCoin <= 1860) {
            // 第3等级
            userLevelMap.put("level", 3);
            userLevelMap.put("topCoin", 1860);

        } else if (todayCoin > 1860 && todayCoin <= 3260) {
            // 第4等级
            userLevelMap.put("level", 4);
            userLevelMap.put("topCoin", 3260);

        } else if (todayCoin > 3260 && todayCoin <= 5360) {
            // 第5等级
            userLevelMap.put("level", 5);
            userLevelMap.put("topCoin", 5360);

        } else if (todayCoin > 5360 && todayCoin <= 9560) {
            // 第6等级
            userLevelMap.put("level", 6);
            userLevelMap.put("topCoin", 9560);

        } else if (todayCoin > 9560 && todayCoin <= 15860) {
            // 第7等级
            userLevelMap.put("level", 7);
            userLevelMap.put("topCoin", 15860);

        } else if (todayCoin > 15860 && todayCoin <= 25260) {
            // 第8等级
            userLevelMap.put("level", 8);
            userLevelMap.put("topCoin", 25260);

        } else if (todayCoin > 25260 && todayCoin <= 37860) {
            // 第9等级
            userLevelMap.put("level", 9);
            userLevelMap.put("topCoin", 37860);

        } else if (todayCoin > 37860 && todayCoin <= 53560) {
            // 第10等级
            userLevelMap.put("level", 10);
            userLevelMap.put("topCoin", 53560);

        } else if (todayCoin > 15700 && todayCoin <= 72460) {
            // 第11等级
            userLevelMap.put("level", 11);
            userLevelMap.put("topCoin", 72460);

        } else if (todayCoin > 72460 && todayCoin <= 99760) {
            // 第12等级
            userLevelMap.put("level", 12);
            userLevelMap.put("topCoin", 99760);

        } else if (todayCoin > 99760 && todayCoin <= 137560) {
            // 第13等级
            userLevelMap.put("level", 13);
            userLevelMap.put("topCoin", 137560);

        } else if (todayCoin > 137560 && todayCoin <= 187960) {
            // 第14等级
            userLevelMap.put("level", 14);
            userLevelMap.put("topCoin", 187960);

        } else if (todayCoin > 187960 && todayCoin <= 253060) {
            // 第15等级
            userLevelMap.put("level", 15);
            userLevelMap.put("topCoin", 253060);

        } else {
            // 错误
            userLevelMap.put("level", 1);
            userLevelMap.put("topCoin", 60);
        }

        return userLevelMap;
    }
}
